package com.qvtu.poetry.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qvtu.poetry.entry.Poem;
import com.qvtu.poetry.entry.dto.*;
import com.qvtu.poetry.service.PoemService;
import com.qvtu.poetry.mapper.PoemMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qvtu.poetry.mapper.UserActionMapper;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zxz
 */
@Service
public class PoemServiceImpl extends ServiceImpl<PoemMapper, Poem> implements PoemService {

    @Autowired
    private ChatClient chatClient;

    @Autowired
    private PoemMapper poemMapper;

    @Autowired
    private UserActionMapper userActionMapper;

    @Override
    public Page<Poem> searchPage(PoemSearchDTO dto) {
        LambdaQueryWrapper<Poem> qw = new LambdaQueryWrapper<>();
        // 只返回已发布作品
        qw.eq(Poem::getStatus, 1);

        String keyword = dto.getKeyword();
        String styleType = dto.getStyleType();
        String themeKeyword = dto.getThemeKeyword();
        LocalDateTime startTime = dto.getStartTime();
        LocalDateTime endTime = dto.getEndTime();
        Integer minLikes = dto.getMinLikes() == null ? 0 : dto.getMinLikes();
        Integer pageNum = (dto.getPageNum() == null || dto.getPageNum() <= 0) ? 1 : dto.getPageNum();
        Integer pageSize = (dto.getPageSize() == null || dto.getPageSize() <= 0) ? 9 : dto.getPageSize();
        if (pageSize > 100) pageSize = 100; // 上限保护
        String order = (dto.getOrder() == null || dto.getOrder().isBlank()) ? "default" : dto.getOrder();

        // 兼容中文与英文排序描述
        String normalizedOrder;
        String trimmed = order.trim();
        switch (trimmed) {
            case "默认", "default" -> normalizedOrder = "default";
            case "最新", "最新发布", "latest" -> normalizedOrder = "latest";
            case "点赞最多", "likes", "like", "most_likes" -> normalizedOrder = "likes";
            case "热度", "hot" -> normalizedOrder = "hot";
            case "分享", "share" -> normalizedOrder = "share";
            default -> normalizedOrder = trimmed.toLowerCase();
        }

        if (keyword != null && !keyword.isBlank()) {
            qw.and(q -> q.like(Poem::getTitle, keyword)
                    .or().like(Poem::getContent, keyword)
                    .or().like(Poem::getThemeKeyword, keyword)
                    .or().like(Poem::getStyleType, keyword));
        }
        if (styleType != null && !styleType.isBlank() && !"全部".equalsIgnoreCase(styleType) && !"all".equalsIgnoreCase(styleType)) {
            qw.eq(Poem::getStyleType, styleType);
        }
        if (themeKeyword != null && !themeKeyword.isBlank()) {
            qw.like(Poem::getThemeKeyword, themeKeyword);
        }
        if (startTime != null) {
            qw.ge(Poem::getCreateTime, startTime);
        }
        if (endTime != null) {
            qw.le(Poem::getCreateTime, endTime);
        }
        if (minLikes != null && minLikes > 0) {
            // 使用子查询过滤点赞达标的诗歌（按你的库与表名填写 schema）
            qw.inSql(Poem::getId,
                    "select poem_id from poetry_system.t_like where is_canceled = 0 group by poem_id having count(1) >= " + minLikes);
        }

        // 排序
        switch (normalizedOrder) {
            case "latest" -> qw.orderByDesc(Poem::getCreateTime);
            case "hot" -> qw.orderByDesc(Poem::getViewCount);
            case "share" -> qw.orderByDesc(Poem::getShareCount);
            case "likes" ->
                    qw.last("ORDER BY (SELECT COUNT(1) FROM poetry_system.t_like l WHERE l.poem_id = t_poem.id AND l.is_canceled = 0) DESC, update_time DESC");
            default -> qw.orderByDesc(Poem::getUpdateTime);
        }

        Page<Poem> page = new Page<>(pageNum, pageSize);
        return this.page(page, qw);
    }

    @Override
    public Poem getPublishedById(Long id) {
        Poem poem = this.getById(id);
        if (poem == null || poem.getStatus() == null || poem.getStatus() != 1) {
            return null;
        }
        return poem;
    }

    @Override
    public Page<Poem> listPublishedPage(Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageNum <= 0) pageNum = 1;
        if (pageSize == null || pageSize <= 0) pageSize = 9;
        if (pageSize > 100) pageSize = 100; // 上限保护

        LambdaQueryWrapper<Poem> qw = new LambdaQueryWrapper<>();
        qw.eq(Poem::getStatus, 1)
                .orderByDesc(Poem::getUpdateTime);

        Page<Poem> page = new Page<>(pageNum, pageSize);
        return this.page(page, qw);
    }

    @Override
    public Page<Poem> listUserPage(Long userId, Integer pageNum, Integer pageSize, Integer status) {
        if (pageNum == null || pageNum <= 0) pageNum = 1;
        if (pageSize == null || pageSize <= 0) pageSize = 9;
        if (pageSize > 100) pageSize = 100;

        LambdaQueryWrapper<Poem> qw = new LambdaQueryWrapper<>();
        qw.eq(Poem::getUserId, userId);
        if (status != null) {
            qw.eq(Poem::getStatus, status);
        } else {
            // 默认排除已删除
            qw.ne(Poem::getStatus, 2);
        }
        qw.orderByDesc(Poem::getUpdateTime);

        Page<Poem> page = new Page<>(pageNum, pageSize);
        return this.page(page, qw);
    }

    // 模型调用
    @Override
    public String generatePoem(PoemCreateDTO req) {
        String prompt = buildPrompt(req);
        return chatClient.prompt()
                .user(prompt)
                .call()
                .content();
    }

    @Override
    public PoemGenerateResp generatePoemStructured(PoemCreateDTO req) {
        // 调用AI生成诗歌的原始内容
        String raw = generatePoem(req);
        // 数据处理
        System.out.println("原始内容：" + raw);
        // 创建响应对象
        PoemGenerateResp resp = new PoemGenerateResp();
        // 携带原始入参
        resp.setParams(req);

        // 如果AI返回为空，则设置默认标题和空内容
        if (raw == null || raw.isBlank()) {
            resp.setTitle(req.getTopic() == null || req.getTopic().isBlank() ? "无题" : req.getTopic());
            resp.setContent("");
            return resp;
        }

        // 对原始内容进行规范化处理
        String normalized = normalizeRaw(raw);           // 统一换行符和空白字符
        normalized = removeThinkBlocks(normalized);      // 移除AI思考过程块<think>
        normalized = stripLeadingExplanations(normalized); // 去除前导解释文字

        // 将处理后的文本按行分割
        String[] lines = normalized.split("\n");
        // 找到诗歌内容的起始位置
        int poemStartIdx = findPoemStartIndex(lines);

        // 如果找不到诗歌内容，返回默认结果
        if (poemStartIdx == -1) {
            resp.setTitle(req.getTopic() == null || req.getTopic().isBlank() ? "无题" : req.getTopic());
            resp.setContent("");
            return resp;
        }

        // 提取标题逻辑：
        String titleCandidate = null;
        int titleLineIdx = poemStartIdx; // 默认使用第一行诗句作为标题

        // 优先尝试使用诗歌前一行作为标题（如果符合标题特征）
        if (poemStartIdx - 1 >= 0) {
            String prev = lines[poemStartIdx - 1].trim();
            if (!prev.isBlank() && looksLikeTitle(prev)) {
                titleCandidate = prev;
                titleLineIdx = poemStartIdx - 1; // 记录标题所在行索引
            }
        }

        // 如果前面没有合适的标题，尝试使用第一行诗句作为标题
        if (titleCandidate == null) {
            String firstPoemLine = lines[poemStartIdx].trim();
            if (looksLikeTitle(firstPoemLine)) {
                titleCandidate = firstPoemLine;
            }
        }

        // 设置最终标题：优先使用提取的标题，否则使用请求中的主题，最后兜底"无题"
        if (titleCandidate == null || titleCandidate.isBlank()) {
            resp.setTitle(req.getTopic() == null || req.getTopic().isBlank() ? "无题" : req.getTopic());
        } else {
            resp.setTitle(titleCandidate);
        }

        // 提取正文内容：
        // 确定正文开始位置：如果第一行诗句被用作标题，则从下一行开始
        int bodyStart = (titleLineIdx == poemStartIdx) ? poemStartIdx + 1 : poemStartIdx;

        // 逐行收集诗歌正文
        StringBuilder body = new StringBuilder();
        for (int i = bodyStart; i < lines.length; i++) {
            String ln = lines[i].trim();
            if (ln.isBlank()) continue;              // 跳过空行
            if (!isPoemLine(ln)) break;              // 遇到非诗句则停止
            if (body.length() > 0) body.append('\n'); // 添加换行符
            body.append(ln);                         // 添加诗句内容
        }

        // 设置最终的诗歌正文内容
        resp.setContent(body.toString());
        return resp;
    }


    /**
     * 规范化原始文本
     */
    private String normalizeRaw(String raw) {
        String s = raw.replace("\r\n", "\n").replace("\r", "\n");
        s = s.replaceAll(" +\n", "\n"); // 去除 Markdown 双空格换行
        s = s.replace('\u3000', ' ');      // 全角空白统一
        return s;
    }

    /**
     * 移除 <think> 块及其内容
     */
    private String removeThinkBlocks(String s) {
        s = s.replaceAll("(?is)<think>.*?</think>", "");
        s = s.replaceAll("(?im)^\n*\s*<think>\s*\n*", "\n");
        return s.trim();
    }

    /**
     * 去除前导解释段，保留从诗歌块附近开始的文本
     */
    private String stripLeadingExplanations(String s) {
        String[] lines = s.split("\n");
        int start = findPoemStartIndex(lines);
        if (start == -1) return s.trim();
        StringBuilder sb = new StringBuilder();
        int begin = Math.max(0, start - 1);
        for (int i = begin; i < lines.length; i++) {
            String ln = lines[i].trim();
            if (ln.isBlank()) continue;
            sb.append(ln).append('\n');
        }
        return sb.toString().trim();
    }

    /**
     * 判断是否像标题
     */
    private boolean looksLikeTitle(String line) {
        if (line == null) return false;
        String l = line.trim();
        if (l.isBlank()) return false;
        if (l.contains("<") || l.contains(">")) return false;
        if (l.length() > 20) return false;
        if (l.matches(".*[A-Za-z0-9].*")) return false; // 排除英数
        String punct = "，。！？、；：,.!?";
        String end = l.substring(l.length() - 1);
        return !punct.contains(end);
    }

    /**
     * 判断诗歌行（主要为中文及中文标点）
     */
    private boolean isPoemLine(String line) {
        String l = line.trim();
        if (l.isBlank()) return false;
        if (l.length() < 2 || l.length() > 40) return false;
        if (l.contains("<") || l.contains(">")) return false;
        if (l.matches(".*[A-Za-z].*")) return false;
        if (l.matches(".*[:;].*")) return false;
        return l.matches("[\\p{IsHan}，。！？、；：“”‘’（）《》·—]+");
    }

    /**
     * 连续诗行的起始位置
     */
    private int findPoemStartIndex(String[] lines) {
        for (int i = 0; i < lines.length; i++) {
            String a = lines[i].trim();
            if (!isPoemLine(a)) continue;
            if (i + 1 < lines.length && isPoemLine(lines[i + 1].trim())) {
                return i;
            }
        }
        return -1;
    }

    private String buildPrompt(PoemCreateDTO r) {
        StringBuilder sb = new StringBuilder();
        sb.append("请根据以下要求创作一首中文诗歌。\\n");
        if (r.getTopic() != null && !r.getTopic().isBlank()) sb.append("题材/主题：").append(r.getTopic()).append("\\n");
        if (r.getGenre() != null && !r.getGenre().isBlank()) sb.append("体裁：").append(r.getGenre()).append("\\n");
        if (r.getStyle() != null && !r.getStyle().isBlank()) sb.append("风格：").append(r.getStyle()).append("\\n");
        if (r.getEmotion() != null && !r.getEmotion().isBlank())
            sb.append("情感：").append(r.getEmotion()).append("\\n");
        if (r.getIntention() != null && !r.getIntention().isBlank())
            sb.append("意向：").append(r.getIntention()).append("\\n");
        if (r.getAllusion() != null && !r.getAllusion().isBlank())
            sb.append("用典：").append(r.getAllusion()).append("\\n");
        if (r.getAcrostic() != null && !r.getAcrostic().isBlank()) {
            sb.append("请以短语“").append(r.getAcrostic()).append("”作为藏头，确保每句首字依次组成该短语。\\n");
        }
        sb.append("他们要符合以上的描述词，不以题材/主题为标题");
        sb.append("格式要求：第一行仅为标题（不加引号、不以句读结束），其后为正文，每句换行；不要附加解释或标注，仅输出标题与正文。不展示思考过程，不输出<think>块或推理。");
//        sb.append(" /no_think");
        System.out.println("prompt: 提示词：" + sb.toString());
        return sb.toString();
    }

    @Override
    public boolean addPoem(Long userId, PoemAddDTO poemAddDTO) {
        // 创建诗歌对象
        Poem poem = new Poem();
        poem.setUserId(userId);
        poem.setTitle(poemAddDTO.getTitle());
        poem.setContent(poemAddDTO.getContent());
        poem.setStatus(poemAddDTO.getStatus());
        poem.setCreateTime(LocalDateTime.now());
        poem.setUpdateTime(LocalDateTime.now());

        // 设置新增字段：将genre放入style-type
        poem.setStyleType(poemAddDTO.getGenre());

        // 设置theme_keyword：整合emotion和intention
        StringBuilder themeKeywordBuilder = new StringBuilder();
        if (poemAddDTO.getEmotion() != null && !poemAddDTO.getEmotion().isBlank()) {
            themeKeywordBuilder.append(poemAddDTO.getEmotion());
        }
        if (poemAddDTO.getIntention() != null && !poemAddDTO.getIntention().isBlank()) {
            if (themeKeywordBuilder.length() > 0) {
                themeKeywordBuilder.append(", ");
            }
            themeKeywordBuilder.append(poemAddDTO.getIntention());
        }
        poem.setThemeKeyword(themeKeywordBuilder.toString());

        // 设置默认值
        poem.setShareCount(0);
        poem.setViewCount(0);

        // 保存到数据库
        return this.save(poem);
    }

    @Override
    public int countUserPoems(Long userId) {
        LambdaQueryWrapper<Poem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Poem::getUserId, userId);
        // 只统计非删除状态的诗歌
        queryWrapper.ne(Poem::getStatus, 2);
        return Math.toIntExact(this.count(queryWrapper));
    }

    @Override
    public Page<PoemWithUserActionDTO> listPublishedPageWithUserAction(Integer pageNum, Integer pageSize, Long userId) {
        // 获取已发布的诗歌分页列表
        Page<Poem> poemPage = this.listPublishedPage(pageNum, pageSize);

        // 调用通用的处理方法
        return processPoemWithUserAction(poemPage, userId);
    }

    @Override
    public Page<PoemWithUserActionDTO> searchPageWithUserAction(PoemListDTO dto) {
        // 确保dto不为null且分页参数有效
        if (dto == null) {
            dto = new PoemListDTO();
            dto.setPageNum(1);
            dto.setPageSize(9);
            dto.setMinLikes(0);
            dto.setOrder("default");
        } else {
            if (dto.getPageNum() == null || dto.getPageNum() <= 0) dto.setPageNum(1);
            if (dto.getPageSize() == null || dto.getPageSize() <= 0) dto.setPageSize(9);
            if (dto.getMinLikes() == null) dto.setMinLikes(0);
            if (dto.getOrder() == null || dto.getOrder().isBlank()) dto.setOrder("default");
        }

        // 调用searchPage获取搜索结果
        Page<Poem> poemPage = this.searchPage(dto);

        // 调用通用的处理方法
        return processPoemWithUserAction(poemPage, dto.getUserId());
    }

    /**
     * 通用处理方法：将诗歌分页结果转换为带用户操作状态的分页结果
     */
    private Page<PoemWithUserActionDTO> processPoemWithUserAction(Page<Poem> poemPage, Long userId) {
        // 创建新的分页结果，用于返回带用户操作状态的诗歌
        Page<PoemWithUserActionDTO> resultPage = new Page<>();
        resultPage.setCurrent(poemPage.getCurrent());
        resultPage.setSize(poemPage.getSize());
        resultPage.setTotal(poemPage.getTotal());
        resultPage.setPages(poemPage.getPages());

        // 如果没有数据，直接返回空结果
        if (poemPage.getRecords().isEmpty()) {
            resultPage.setRecords(List.of());
            return resultPage;
        }

        // 提取诗歌ID列表
        List<Long> poemIds = poemPage.getRecords().stream()
                .map(Poem::getId)
                .toList();

        // 查询点赞总数
        Map<Long, Integer> likeCountMap = new HashMap<>();
        if (!poemIds.isEmpty()) {
            List<Map<String, Object>> likeCounts = userActionMapper.countLikesByPoemIds(poemIds);
            for (Map<String, Object> likeCount : likeCounts) {
                Long poemId = Long.valueOf(likeCount.get("poemId").toString());
                Integer count = Integer.valueOf(likeCount.get("likeCount").toString());
                likeCountMap.put(poemId, count);
            }
        }

        // 查询用户操作状态
        Map<Long, Integer> userActionMap = new HashMap<>();
        if (userId != null && !poemIds.isEmpty()) {
            List<Map<String, Object>> userActions = userActionMapper.getUserActionsByPoemIds(userId, poemIds);
            for (Map<String, Object> userAction : userActions) {
                Long poemId = Long.valueOf(userAction.get("poemId").toString());
                Integer actionType = Integer.valueOf(userAction.get("actionType").toString());
                userActionMap.put(poemId, actionType);
            }
        }

        // 转换为PoemWithUserActionDTO
        List<PoemWithUserActionDTO> records = poemPage.getRecords().stream().map(poem -> {
            PoemWithUserActionDTO dto = new PoemWithUserActionDTO();
            // 复制原有诗歌信息
            dto.setId(poem.getId());
            dto.setUserId(poem.getUserId());
            dto.setTitle(poem.getTitle());
            dto.setContent(poem.getContent());
            dto.setStatus(poem.getStatus());
            dto.setCreateTime(poem.getCreateTime());
            dto.setUpdateTime(poem.getUpdateTime());
            dto.setStyleType(poem.getStyleType());
            dto.setThemeKeyword(poem.getThemeKeyword());
            dto.setShareCount(poem.getShareCount());
            dto.setViewCount(poem.getViewCount());

            // 设置点赞总数
            dto.setLikeCount(likeCountMap.getOrDefault(poem.getId(), 0));

            // 设置用户操作状态
            Integer actionType = userActionMap.getOrDefault(poem.getId(), 0);
            dto.setLiked(actionType == 1 || actionType == 3); // 1-点赞，3-点赞+收藏
            dto.setCollected(actionType == 2 || actionType == 3); // 2-收藏，3-点赞+收藏

            return dto;
        }).toList();

        resultPage.setRecords(records);
        return resultPage;
    }
}




